<template>
  <!--菜单管理-->
  <el-row style="height:100%">
    <page @buttons="configPermissions">
      <pageheader :event="'menuPopUp'" :isShow="buttonPermissions.isAdd">
        菜单管理
      </pageheader>
      <div class="page-content">
        <el-card class="box-card">
          <TreeTable
            class="pad_left_30table"
            :tableData="dataTable"
            :columns="columns"
            @menuData="menuData"
            @menuDel="menuDel"
            @menuSetUse="menuSetUse"
            :setUseEvent="'menuSetUse'"
            :openRowName="'menuOpenRow'"
            border
          ></TreeTable>
        </el-card>
        <el-dialog v-dialogDrag :title="pageTitle" :visible.sync="isShow" @close="closeDialog('ruleForm')"
                   :modal-append-to-body="false" :close-on-click-modal="false" width="800px">
          <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="180px">
            <el-form-item label="菜单名称" prop="menu_name">
              <el-input v-model="ruleForm.menu_name" size="small" style="width:450px"></el-input>
            </el-form-item>
            <el-form-item label="菜单名称图标" prop="icon">
              <el-input v-model="ruleForm.icon" size="small" style="width:450px"></el-input>
            </el-form-item>
            <el-form-item label="菜单URL" prop="menu_url">
              <el-input v-model="ruleForm.menu_url" size="small" style="width:450px"></el-input>
            </el-form-item>
            <el-form-item label="所属上级菜单" prop="parent_id_arr">
              <Cascader :value.sync="ruleForm.parent_id_arr"
                        :options="options"
                        :changeEvent="'menuChange'"
                        :width="'450px'"
                        :disabled="isDisabled"></Cascader>
            </el-form-item>
            <el-form-item label="菜单类型" prop="menu_type">
              <el-radio-group v-model="ruleForm.menu_type" size="small" :disabled="isDisabled">
                <el-radio v-for="item in menuTypeList" :label="item.value" :key="item.value">{{item.label}}</el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="菜单序号" prop="sort_num">
              <el-input v-model="ruleForm.sort_num" size="small" style="width:450px"></el-input>
            </el-form-item>
            <el-form-item label="菜单Code" prop="menu_code">
              <el-input v-model="ruleForm.menu_code" size="small" style="width:450px"></el-input>
            </el-form-item>
            <el-form-item v-show="ruleForm.menu_type != 0" label="菜单API" prop="api_code_arr">
              <el-select v-model="ruleForm.api_code_arr" size="small" multiple filterable placeholder="请选择"
                         style="width:450px">
                <el-option
                  v-for="(item,index) in menuAPIList"
                  :key="item.name+'-'+item.code + index"
                  :label="item.name+'-'+item.code"
                  :value="item.code">
                  <el-tooltip v-if="item.describe" effect="dark" :content="item.describe" placement="right">
                    <span>
                      {{ item.name+'-'+item.code }}
                      <i class="el-icon-question"></i>
                    </span>
                    <span v-if="!item.describe">{{ item.name+'-'+item.code }}</span>
                  </el-tooltip>
                </el-option>
              </el-select>
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click="isShow = false" size="small">取 消</el-button>
            <!--判断是否显示保存按钮：isDisabled 判断为是否为修改页面 -->
            <el-button v-if="(!isDisabled && buttonPermissions.isAdd) || (isDisabled && buttonPermissions.isModify)"
                       type="primary" @click="confirmDialog('ruleForm')" size="small">保 存</el-button>
          </div>
        </el-dialog>
      </div>
    </page>
  </el-row>
</template>
<style lang="scss">
  .page-content {
    padding: 15px;
    .fr {
      float: right;
    }
    .el-table {
      margin-bottom: 10px;
    }
    .paging {
      margin: 15px;
      height: 28px;
    }
    .pad_left_30table{
      .el-table{
        .el-table__header-wrapper{
          .has-gutter{
            tr{
              th{
                &:first-child{
                  >.cell{
                    padding-left: 30px;
                  }
                }
              }
            }
          }
        }
        .el-table__body-wrapper{
          .el-table__body{
            tbody{
              tr{
                td{
                  &:first-child{
                   >.cell{
                   padding-left: 30px;
                   }                     
                  }
                }
              }
            }
          }
        }
      }
    }
  }
</style>
<script>
import page from "@/components/page/page";
import pageheader from "@/components/page/pageheader";
import Cascader from "@/components/sys/assembly/elcascader";
import TreeTable from "@/components/sys/assembly/treeTable";

export default {
  data() {
    let validateSortNum = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入菜单序号'));
      } else {
        let str = /^[0-9-]+$/
        if(!str.test(value)){
          callback(new Error('菜单序号只允许输入整数'));
        }
        callback();
      }
    }
    return {
      pageTitle: "用户管理信息",
      isShow: false,//是否显示模态框
      isDisabled:false,//是否是修改状态
      ruleForm: {
        menu_name: '',//菜单名称
        icon: '',//菜单名称图标
        menu_code: '',//菜单code
        menu_url: '',//菜单URL
        menu_type: 0,//菜单类型
        parent_id:'',//所属上级菜单str(回传参数)
        parent_id_arr:[],//所属上级菜单arr(插件显示参数)
        api_code_str: '',//菜单APIstr(回传参数)
        api_code_arr: [],//菜单APIarr(插件显示参数)
        is_use:0,//是否启用
        sort_num:100,//菜单序号
      },//模态框form表单
      rules: {
        menu_name: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
        sort_num:[{ required: true, validator:validateSortNum, trigger: "blur" }]
      },//form表单验证
      menuTypeList:[
        {
          label:'父菜单',
          value:0,
        },
        {
          label:'子菜单',
          value:1,
        },
        {
          label:'按钮',
          value:2,
        },
      ],//菜单类型
      menuAPIList:[],//菜单API
      options:[],//级联控件 所属上级菜单
      dataTable:[],//表格数据
      columns:[
        {
          text: "菜单名称",
          value: "menu_name",
          align: "left",
          showOverflowTooltip:true,
          width: 300
        },
        {
          text: "序号",
          value: "",
          align: "center",
          width: 60
        },
        {
          text: "菜单Url",
          value: "menu_url",
          align: "center",
          //  width: 200
        },
        {
          text: "菜单类型",
          value: "menu_type_name",
          align: "center",
          width: 100,
        },
        {
          text: "菜单Code",
          value: "menu_code",
          align: "center",
          //  width: 200
        },
        {
          text: "菜单序号",
          value: "sort_num",
          align: "center",
          width: 80
        },
        {
          text: "是否启用",
          value: "is_use_name",
          align: "center",
          width: 120,
          is_use:true
        },
        {
          text: "操作",
          value: "",
          align: "center",
          width: 180,
          button:[]
        }
      ],//表头参数
      buttonPermissions:{
        isAdd:false,
        isDel:false,
        isModify:false,
        isWatch:false,
        isUse:false,
      },
      openRow:new Set(),//设置set数据结构存储表格展开行数据
      expandRowKeys:[],
    };
  },
  inject: ["reload"],
  components: {
    page,
    pageheader,
    Cascader,//级联选择器组件
    TreeTable//表格组件
  },
  created() {
    //判断是否有按钮权限
    if(sessionStorage.buttonPermissions){
      this.configPermissions(JSON.parse(sessionStorage.buttonPermissions))
    }
    //页面初始化
    this.getReady();
  },
  mounted() {
    //新增按钮点击事件
    this.$Bus.$on("menuPopUp", () => {
      this.isShow = true;
      this.isDisabled = false;
    });
    //级联change事件
    this.$Bus.$on("menuChange", data => {
      this.ruleForm.parent_id_arr = data
      this.ruleForm.parent_id = data.slice(-1)[0]
    });
  },
  beforeDestroy(){
    //销毁Bus绑定事件
    this.$Bus.$off("menuPopUp")
    this.$Bus.$off("menuChange")
  },
  methods: {
    //配置按钮权限，根据权限不同调整表头渲染参数
    configPermissions(val){
      let buttonPermissions = val
      let menuButtonPermissions = [];//按钮权限数组
      let is_use_obj = {
        text: "是否启用",
        value: "is_use_name",
        align: "center",
        width: 120,
        is_use:true
      };//是否启用
      let operation = {
        text: "操作",
        value: "",
        align: "center",
        width: 180,
        button:[]
      };//操作
      buttonPermissions.forEach(e =>{
        for(let key in e){
          if(key == 'menu_code'){
            menuButtonPermissions.push(e[key])
          }
        }
      });
      this.buttonPermissions.isAdd = menuButtonPermissions.includes('menuAdd') ? true : false; //是否有新增权限
      this.buttonPermissions.isDel = menuButtonPermissions.includes('menuDelete') ? true : false; //是否有删除权限
      this.buttonPermissions.isModify = menuButtonPermissions.includes('menuModify') ? true : false; //是否有修改权限
      this.buttonPermissions.isWatch = menuButtonPermissions.includes('menuWatch') ? true : false; //是否有查看权限
      this.buttonPermissions.isUse = menuButtonPermissions.includes('menuUse') ? true : false; //是否有启用权限

      //启用权限配置
      is_use_obj.is_use = this.buttonPermissions.isUse
      this.columns.splice(-2,1,is_use_obj)

      //查看和删除权限配置 当查看和删除权限都没有的时候则不push operation
      if(this.buttonPermissions.isWatch || this.buttonPermissions.isDel){
        if(this.buttonPermissions.isWatch){
          operation.button.push({
            name:'详情',
            type:'',
            event:'menuData',
          },)
        }
        if(this.buttonPermissions.isDel){
          operation.button.push( {
            name:'删除',
            type:'danger',
            event:'menuDel',
          },)
        }
      }
      this.columns.splice(-1,1,operation)
    },
    //页面初始化
    getReady(){
      //获取所有菜单列表
      let getMenuTreeAll = ()=>{
        let p = new Promise((res,rej)=>{
          let url = '/sys/menu/tree_all';
          this.$api.get(url)
          .then(data => {
            if(data == '10001'){
              this.$message.error('无权操作该数据')
              this.$Bus.$emit('Loading',false);
              return
            }
            if(data){
              recursion(data.data);
              function recursion(val) {
                if(val.length){
                  for(let i in val){
                    val[i].value = val[i].id;
                    val[i].label = val[i].menu_name;
                    val[i].menu_type_name = val[i].menu_type == 0 ? '父菜单' :
                      val[i].menu_type == 1 ? '子菜单' : '按钮';
                    val[i].is_use_name = val[i].is_use ? '已启用' : '未启用'
                    if(val[i].children && val[i].children.length){
                      recursion(val[i].children)
                    }else{
                      delete val[i].children
                    }
                  }
                }
              }
              this.options = data.data
              this.dataTable = data.data
              res()
            }else{
              rej()
            }
          })
          //回传参数为空试
          .catch(err=>{
             console.log(err);
            this.options = [];
            this.dataTable = [];
            rej()
          })
        })
        return p
      }
      //获取菜单api
      let getApiAllList = ()=>{
        let p = new Promise((res,rej)=>{
          let url = '/sys/backendapi/all_list'
          this.$api.get(url)
          .then(data => {
            if(data == '10001'){
              this.$message.error('无权操作该数据')
              this.$Bus.$emit('Loading',false);
              return
            }
            if(data){
              this.menuAPIList =data.data
              res()
            }else{
              rej()
            }
          })
          //回传参数为空试
          .catch(err=>{
             console.log(err);
            this.menuAPIList = [];
            rej()
          })
        })
        return p
      }
      //判断是否存有菜单，如果没有则调用接口
      Promise.all([getMenuTreeAll(),getApiAllList()])
      .then(()=>{
        // console.log('全部执行完毕');
        this.$Bus.$emit('Loading',false)
      })
      .catch(()=>{
        console.log('失败了');
        this.$Bus.$emit('Loading',false)
      })
    },
    //关闭模态框
    closeDialog(formName){
      this.ruleForm.id = '';
      this.$refs[formName].resetFields();
      this.$Bus.$emit('Loading',false)
    },
    //获取菜单信息
    getRuleForm(id){
      let url = '/sys/menu/get'
      let data = {
        id:id
      }
      this.$api.get(url,data)
      .then(data => {
        if(data == '10001'){
          this.$message.error('无权操作该数据')
          this.$Bus.$emit('Loading',false);
          return
        }
        if(data){
          let _data = data.data
          //设置菜单API参数
          if(_data.api_list.length){
            _data.api_code_arr = [];
            for(let i in _data.api_list){
              _data.api_code_arr.push(_data.api_list[i].code)
            }
          }
          //所属上级菜单参数
          if(_data.node_location){
            let arr = _data.node_location.split('-')
            _data.parent_id_arr = [];
            if(arr.length > 1){
              recursion(0,this.options)
            }
            function recursion(n,obj) {
              if(n == arr.length - 1){
                return
              }else{
                for(let i in obj){
                  if(arr[n] == obj[i].id){
                    _data.parent_id_arr.push(obj[i].id)
                    n++
                    recursion(n,obj[i].children)
                  }
                }
              }
            }
          }
          this.ruleForm = Object.assign(this.ruleForm,_data)
        }else{
          this.isShow = false;
        }
        this.$Bus.$emit('Loading',false)
      })
      .catch(err=>{
         console.log(err);
        this.$Bus.$emit('Loading',false)
      })
    },
    //修改按钮点击事件
    menuData(data){
      this.isShow = true;
      this.isDisabled = true;
      this.$Bus.$emit('Loading',true)
      this.getRuleForm(data.id)
    },
    //模态框保存按钮
    confirmDialog(formName){
      let data = {};
      let model = null;
      let url = ''
      this.$refs[formName].validate(valid => {
        if (valid) {
          this.$Bus.$emit('Loading',true)
          model = this.$refs[formName].model;
          model.api_code_str = model.api_code_arr.length !== 0 ? model.api_code_arr.join(',') : '';
          model.parent_id = model.parent_id_arr.length !== 0 ? model.parent_id_arr.slice(-1)[0] : '';
          if (this.isDisabled) {
            data.api_code_str = model.api_code_str
            data.icon = model.icon
            data.menu_code = model.menu_code
            data.menu_name = model.menu_name
            data.menu_url = model.menu_url
            data.sort_num = parseInt(model.sort_num);
            url = "sys/menu/update?id=" + model.id;
            this.modifyMenu(url, data);
          } else {
            data.api_code_str = model.api_code_str
            data.icon = model.icon
            data.menu_code = model.menu_code
            data.menu_name = model.menu_name
            data.menu_type = model.menu_type
            data.menu_url = model.menu_url
            data.parent_id = model.parent_id
            data.sort_num = parseInt(model.sort_num)
            url = "sys/menu/add";
            this.addMenu(url, data);
          }
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    //新增保存
    addMenu(url, data) {
      this.$api.post(url, data)
      .then(data => {
        if(data == '10001'){
          this.$message.error('无权操作该数据')
          this.$Bus.$emit('Loading',false);
          return
        }
        this.$Bus.$emit('Loading',false)
        if(data){
          this.reload();
          this.$message({
            message: "新增成功",
            type: "success"
          });
        }
      })
      .catch(err=>{
         console.log(err);
        this.$Bus.$emit('Loading',false)
      })
    },
    //修改保存
    modifyMenu(url,data){
      this.$api
      .put(url, data)
      .then(data => {
        if(data == '10001'){
          this.$message.error('无权操作该数据')
          this.$Bus.$emit('Loading',false);
          return
        }
        this.$Bus.$emit('Loading',false)
        if(data){
          this.isShow = false
          this.reload();
          this.$message({
            message: "修改成功",
            type: "success"
          });
        }
      })
      .catch(err=>{
         console.log(err);
        this.$Bus.$emit('Loading',false)
      })
    },
    //删除按钮点击事件
    menuDel(data){
      this.$confirm("是否删除‘"+ data.menu_name +"’？如删除条目包含子条目则一同删除！", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        center: true
      })
      .then(() => {
        this.$Bus.$emit('Loading',true)
        this.delData(data.id);
      })
      .catch(()=>{})
    },
    //删除接口
    delData(id) {
      let url = "/sys/menu/del";
      let data = {
        id:id
      }
      this.$api.delete(url,data)
      .then(data => {
        if(data == '10001'){
          this.$message.error('无权操作该数据')
          this.$Bus.$emit('Loading',false);
          return
        }
        this.$Bus.$emit('Loading',true)
        if(data){
          this.reload();
          this.$message({
            message: "删除成功",
            type: "success"
          });
        }
      })
      .catch(err=>{
         console.log(err);
        this.$Bus.$emit('Loading',false)
      })
    },
    //启用/未启用切换点击事件
    menuSetUse(data){
      let msg = data.is_use ? '菜单关闭将关闭所有子级菜单' : '菜单开启将开启所有父级菜单'
      this.$confirm(msg, "是否切换状态？", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        center:true
      })
      .then(() => {
        this.$Bus.$emit('Loading',true)
        this.setUseMenu(data.id,data.is_use)
      })
      .catch(err=>{
         console.log(err);
        this.$Bus.$emit('Loading',false)
      })
    },
    //启用/未启用切换
    setUseMenu(id,is_use){
      is_use = is_use ? 0 : 1
      let url = '/sys/menu/set_use?id=' + id +'&is_use='+ is_use;
      this.$api.put(url)
      .then(data => {
        if(data == '10001'){
          this.$message.error('无权操作该数据')
          this.$Bus.$emit('Loading',false);
          return
        }
        this.$Bus.$emit('Loading',false)
        if(data){
          this.reload();
          this.$message({
            message: "修改成功",
            type: "success"
          });
        }
      })
      .catch(err=>{
         console.log(err);
        this.$Bus.$emit('Loading',false)
      })
    },
  },
  watch: {}
};
</script>
